package com.mas.session.state;

import jade.lang.acl.ACLMessage;

import java.util.Map;

import com.mas.resource.ResourceAllocator;
import com.mas.resource.ResourceInfo;
import com.mas.session.MonitorSession;
import com.mas.session.Session;
import com.mas.strategey.Proposal;

public class ProcessAcceptState extends AbstractState {

	private Proposal proposal;

	public ProcessAcceptState(Session session) {
		super(session);
	}

	/**
	 * this method is being called only after proposal was accepted. it tries to
	 * allocate the resources, if its succeeded, done message is being sent,
	 * else failure message is sent.
	 * 
	 **/
	public void acceptProposalResponse(ACLMessage message) {
		System.out.println("ProcessAcceptState.acceptProposalResponse()");

		Map mapResourceAllocator = ((MonitorSession)this.session).getMonitorResourceAgent()
				.getMapResourceAllocator();

		ResourceInfo[] resourceInfos = proposal.getResourceInfos();

		allocateResources(message, mapResourceAllocator, resourceInfos);

		DoneExitSenderState state = (DoneExitSenderState) this.session
				.assignState(DoneExitSenderState.class.getName());
		state.proposalAccepted(message);
	}

	private void allocateResources(ACLMessage message,
			Map mapResourceAllocator, ResourceInfo[] resourceInfos) {
		for (int i = 0; i < resourceInfos.length; i++) {
			ResourceInfo curResourceInfo = resourceInfos[i];
			if (!mapResourceAllocator.containsKey(curResourceInfo
					.getResourceName())) {
				assignFailureState(message, "Error, resource:"
						+ curResourceInfo.getResourceName() + " not found");
				return;
			}

			ResourceAllocator resourceAllocator = (ResourceAllocator) mapResourceAllocator
					.get(curResourceInfo.getResourceName());

			if (!resourceAllocator.allocateResource(curResourceInfo
					.getRequiredUsage())) {
				assignFailureState(message, "Error, allocation of resource:"
						+ curResourceInfo.getResourceName()
						+ " failed. current Resource usage:"
						+ curResourceInfo.getResourceCurrentUsage());
				return;
			}

		}
	}

	/**
	 * @return the proposal
	 */
	public Proposal getProposal() {
		return proposal;
	}

	/**
	 * @param proposal
	 *            the proposal to set
	 */
	public void setProposal(Proposal proposal) {
		this.proposal = proposal;
	}
}